import { IPublicTypeJSSlot, isJSSlot, IPublicTypeNodeData } from '@alilc/lowcode-types';
import { CodeGeneratorError, NodeGenerator, IScope } from '../types';
import { unwrapJsExprQuoteInJsx } from './jsxHelpers';

function generateSingleLineComment(commentText: string): string {
  return `/* ${commentText.split('\n').join(' ').replace(/\*\//g, '*-/')}*/`;
}

export function generateJsSlot(slot: any, scope: IScope, generator: NodeGenerator<string>): string {
  if (isJSSlot(slot)) {
    const { title, params, value } = slot as IPublicTypeJSSlot;

    // slot 也是分有参数和无参数的
    // - 有参数的 slot 就是类似一个 render 函数，需要创建子作用域
    // - 无参数的 slot 就是类似一个 JSX 节点，不需要创建子作用域
    const slotScope = params ? scope.createSubScope(params || []) : scope;

    // 创建一个自定义的生成器函数，用于传递JSSlot参数信息
    const slotNodeGenerator = (nodeItem: any, nodeScope: IScope) => {
      // 标记当前作用域中的变量为JSSlot参数
      return generator(nodeItem, nodeScope, { isJSSlotParams: true });
    };

    const contentExpr = !value
      ? 'null'
      : generateNodeDataOrArrayForJsSlot(value, slotNodeGenerator, slotScope);
    if (params) {
      return [
        title && generateSingleLineComment(title),
        '(',
        (params || []).join(', '),
        ') => (', // (__$$context) => (
        contentExpr,
        ')',
        // ))(',
        //   `  __$$createChildContext(__$$context, { ${(params || []).join(', ')} }`,
        //   ')
      ]
        .filter(Boolean)
        .join('');
    }

    return contentExpr || '[]';
  }

  throw new CodeGeneratorError('Not a JSSlot');
}

/**
 * 检测两个条件是否为互补条件（如 text 和 !text）
 */
function isComplementaryConditions(cond1: any, cond2: any): boolean {
  if (!cond1 || !cond2 || typeof cond1 !== 'object' || typeof cond2 !== 'object') {
    return false;
  }

  if (cond1.type !== 'JSExpression' || cond2.type !== 'JSExpression') {
    return false;
  }

  const value1 = cond1.value?.trim() || '';
  const value2 = cond2.value?.trim() || '';

  // 检测 "this.text" 和 "!(this.text)" 的模式
  if (value2 === `!(${value1})` || value1 === `!(${value2})`) {
    return true;
  }

  // 检测 "!this.text" 和 "this.text" 的模式
  if (value1.startsWith('!') && value2 === value1.slice(1)) {
    return true;
  }

  if (value2.startsWith('!') && value1 === value2.slice(1)) {
    return true;
  }

  return false;
}

/**
 * 生成三元表达式
 */
function generateConditionalExpression(
  trueComponent: any,
  falseComponent: any,
  generator: NodeGenerator<string>,
  scope: IScope,
): string {
  // 处理条件表达式，需要去除 this 前缀
  let condition = trueComponent.condition?.value || '';

  // 使用作用域处理逻辑去除 this 前缀
  if (scope && scope.bindings) {
    const bindings = scope.bindings.getAllBindings() || [];
    console.log('【generateConditionalExpression】当前作用域变量:', bindings);
    console.log('【generateConditionalExpression】原始条件:', condition);

    // 处理作用域变量，移除 this. 前缀
    bindings.forEach((binding) => {
      const pattern = new RegExp(`\\bthis\\.${binding}\\b`, 'g');
      if (pattern.test(condition)) {
        console.log(`【generateConditionalExpression】替换 this.${binding} 为 ${binding}`);
        condition = condition.replace(pattern, binding);
      }
    });

    console.log('【generateConditionalExpression】处理后条件:', condition);
  }

  // 清理条件表达式，移除可能的双重否定和多余的括号
  let cleanCondition = condition;
  if (cleanCondition.startsWith('!!')) {
    cleanCondition = cleanCondition.slice(2);
  }
  if (cleanCondition.startsWith('!(') && cleanCondition.endsWith(')')) {
    // 如果是 !(condition) 的形式，提取内部条件并取反
    const innerCondition = cleanCondition.slice(2, -1);
    cleanCondition = `!${innerCondition}`;
  }
  if (cleanCondition.startsWith('(') && cleanCondition.endsWith(')')) {
    cleanCondition = cleanCondition.slice(1, -1);
  }

  // 生成组件的 JSX，需要临时移除 condition 属性避免重复的条件逻辑
  // 创建组件的副本，移除 condition 属性
  const trueComponentCopy = { ...trueComponent };
  const falseComponentCopy = { ...falseComponent };
  delete trueComponentCopy.condition;
  delete falseComponentCopy.condition;

  console.log('【generateConditionalExpression】生成纯净的JSX（无条件逻辑）');
  const trueJsx = unwrapJsExprQuoteInJsx(generator(trueComponentCopy, scope)) || 'null';
  const falseJsx = unwrapJsExprQuoteInJsx(generator(falseComponentCopy, scope)) || 'null';

  console.log('【generateConditionalExpression】最终条件:', cleanCondition);
  console.log('【generateConditionalExpression】真值JSX:', trueJsx);
  console.log('【generateConditionalExpression】假值JSX:', falseJsx);

  return `${cleanCondition} ? ${trueJsx} : ${falseJsx}`;
}

function generateNodeDataOrArrayForJsSlot(
  value: IPublicTypeNodeData | IPublicTypeNodeData[],
  generator: NodeGenerator<string>,
  scope: IScope,
) {
  if (Array.isArray(value)) {
    if (value.length === 0) {
      return '[]';
    }

    if (value.length === 1) {
      return unwrapJsExprQuoteInJsx(generator(value[0], scope)) || 'null';
    }

    // 特殊处理：检测两个互补条件的组件，生成三元表达式
    if (value.length === 2) {
      const [comp1, comp2] = value as any;

      // 检查是否都有条件且为互补条件
      if (
        comp1.condition &&
        comp2.condition &&
        isComplementaryConditions(comp1.condition, comp2.condition)
      ) {
        console.log('【JSSlot】检测到互补条件，生成三元表达式');
        console.log('条件1:', comp1.condition.value);
        console.log('条件2:', comp2.condition.value);

        // 确定哪个是真值分支，哪个是假值分支
        const cond1 = comp1.condition.value?.trim() || '';
        const cond2 = comp2.condition.value?.trim() || '';

        let trueComponent, falseComponent;

        console.log('【JSSlot】分析条件分支:');
        console.log('条件1:', cond1);
        console.log('条件2:', cond2);

        // 判断逻辑：
        // 1. 如果条件1是简单条件（如 "this.text"），条件2是其否定（如 "!(this.text)"），则条件1是真值分支
        // 2. 如果条件1是否定条件（如 "!this.text"），条件2是其肯定（如 "this.text"），则条件2是真值分支

        if (cond2 === `!(${cond1})`) {
          // 条件2是条件1的否定形式：cond1 为真值分支
          console.log('【JSSlot】条件2是条件1的否定形式，条件1为真值分支');
          trueComponent = comp1;
          falseComponent = comp2;
        } else if (cond1 === `!(${cond2})`) {
          // 条件1是条件2的否定形式：cond2 为真值分支
          console.log('【JSSlot】条件1是条件2的否定形式，条件2为真值分支');
          trueComponent = comp2;
          falseComponent = comp1;
        } else if (cond1.startsWith('!') && cond2 === cond1.slice(1)) {
          // 条件1是否定，条件2是肯定：cond2 为真值分支
          console.log('【JSSlot】条件1是否定，条件2是肯定，条件2为真值分支');
          trueComponent = comp2;
          falseComponent = comp1;
        } else if (cond2.startsWith('!') && cond1 === cond2.slice(1)) {
          // 条件2是否定，条件1是肯定：cond1 为真值分支
          console.log('【JSSlot】条件2是否定，条件1是肯定，条件1为真值分支');
          trueComponent = comp1;
          falseComponent = comp2;
        } else {
          // 默认情况：假设第一个是真值分支
          console.log('【JSSlot】使用默认逻辑，条件1为真值分支');
          trueComponent = comp1;
          falseComponent = comp2;
        }

        return generateConditionalExpression(trueComponent, falseComponent, generator, scope);
      }
    }

    // 默认情况：生成数组
    return `[\n${
      value
        .map((v) => {
          if (typeof v === 'string') {
            return JSON.stringify(v);
          }

          return unwrapJsExprQuoteInJsx(generator(v, scope)) || 'null';
        })
        .join(',\n') || 'null'
    }\n]`;
  }

  return unwrapJsExprQuoteInJsx(generator(value, scope)) || 'null';
}
